﻿using System;

namespace MessageSystem.Managed.Rpc
{
    public class RpcControl
    {
        public static void MessageId2ServiceAndMethodId(int nMessageId,ref Int16 nServiceId,ref Int16 nMethodId)
        {
            nServiceId = (Int16)(nMessageId>> 16);
            nMethodId = (Int16)nMessageId;
        }

        public static int MessageIdFromServiceAndMethodId(Int16 nServiceId, Int16 nMethodId)
        {
            Int32 result = (Int32)nMethodId;
            result |= (nServiceId << 16);
            return (int)result;
        }

        public static UInt16 SetNull(UInt16 nFlags)
        {
            return (UInt16)(nFlags | 0x0100);
        }

        public static bool IsNull(UInt16 nFlags)
        {
            return (nFlags & 0x0100) == 0x0100;
        }

        public static UInt16 SetException(UInt16 nFlags)
        {
            return (UInt16)(nFlags | 0x0200);
        }

        public static bool IsException(UInt16 nFlags)
        {
            return (nFlags & 0x0200) == 0x0200;
        }

        public static UInt16 SetReturn(UInt16 nFlags)
        {
            return (UInt16)(nFlags | 0x0400);
        }

        public static bool IsReturn(UInt16 nFlags)
        {
            return (nFlags & 0x0400) == 0x0400;
        }

        public static UInt16 SetRpc(UInt16 nFlags)
        {
            return (UInt16)(nFlags | 0x0800);
        }

        public static bool IsRpc(UInt16 nFlags)
        {
            return (nFlags & 0x0800) == 0x0800;
        }

        public static UInt16 SetEncrypt(UInt16 nFlags)
        {
            return (UInt16)(nFlags | 0x0001);
        }

        public static Int16 GetServiceId(Type serviceType)
        {
            return (Int16)GetHashCode(serviceType.FullName); 
        }

        public static unsafe Int32 GetHashCode(string s)
        {
            fixed (char* str = s)
            {
                char* chPtr = str;
                int num = 352654597;
                int num2 = num;
                int* numPtr = (int*)chPtr;
                for (int i = s.Length; i > 0; i -= 4)
                {
                    num = (((num << 5) + num) + (num >> 27)) ^ numPtr[0];
                    if (i <= 2)
                    {
                        break;
                    }
                    num2 = (((num2 << 5) + num2) + (num2 >> 27)) ^ numPtr[1];
                    numPtr += 2;
                }
                return (num + (num2 * 1566083941));
            }
        }
    }
}
